package fgin

import (
	"errors"
	"fmt"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

// 注册自定义指标, 请求次数counter、请求耗时 Histogram
var (
	// 请求计数, (请求类型, 请求路由, code)
	requestCount *prometheus.CounterVec
	// 请求时间Histogram
	requestHistogram *prometheus.HistogramVec
)

// 注册指标进入
func prometheusRegist() {
	// 请求计数, (请求类型, 请求路由, code)
	requestCount = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: "fgin",
		Name:      fmt.Sprintf("%v_request_total", fginConfig.ServiceName),
		Help:      "Total number of requests.",
	}, []string{"method", "caller", "code"})
	// 请求时间Histogram
	requestHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Namespace: "fgin",
		Name:      fmt.Sprintf("%v_request_duration_seconds", fginConfig.ServiceName),
		Help:      "requests duration(s).",
		Buckets:   []float64{0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10},
	}, []string{"method", "caller", "code"})
	prometheus.MustRegister(requestCount)
	prometheus.MustRegister(requestHistogram)
}

func initPrometheus() {
	if (fginConfig.Prometheus == Prometheus{}) {
		// prometheus 没有配置
		return
	}
	prometheusRegist()
	if fginConfig.NetType == "grpc" {
		switch fginConfig.Env {
		case "pro":
			// 生产模式
			gin.SetMode(gin.ReleaseMode)
		case "dev":
			// 调试模式
			gin.SetMode(gin.DebugMode)
		default:
			panic(errors.New("env配置错误,只支持:pro生产模式,dev调试模式"))
		}
	}
	prometheusRouter := gin.New()
	prometheusRouter.GET(fginConfig.Prometheus.Path, gin.WrapH(promhttp.Handler()))
	prometheusSrv := &http.Server{
		Addr:    fmt.Sprintf("%s:%v", fginConfig.Prometheus.Ip, fginConfig.Prometheus.Port),
		Handler: prometheusRouter,
	}
	go func() {
		// 服务连接
		logSuger.Info(fmt.Sprintf("开启prometheus服务接口: %s:%v%s\n", fginConfig.Prometheus.Ip, fginConfig.Prometheus.Port, fginConfig.Prometheus.Path))
		if err := prometheusSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("prometheus服务 listen err: %v\n", err)
		}
	}()
}
